<?php
/**
 * +--------------------------------------------------------+
 * @Created by Phpstorm.
 * @Category NginxLog.php
 * @Depiction
 * @Author hwy <429208948@qq.com>
 * @Date 2022/3/15  18:14
 * +--------------------------------------------------------+
 */

namespace App\Util;


use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use ErrorException;

class NginxLog
{
    private $filePath;

    public function __construct($filePath)
    {
        $this->filePath = $filePath;
    }

    /**
     * @return \Illuminate\Support\Collection
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
     * @Depiction 获取文件全部数据
     * @Author hwy <429208948@qq.com>
     * @Date 2022/4/2  10:22
     */
    public function get()
    {
        $logs = Storage::disk('logs')->get($this->filePath);
        $logs = explode("\n", $logs);

        $logs_data = [];
        foreach ($logs as $log) {
            if ($log == '') {
                continue;
            }
            $string   = Str::replaceArray('- ', [''], $log);
            $keywords = preg_split("/[\"*]/", $string);
            $array    = [];
            // 数据处理
            foreach ($keywords as $key => $keyword) {
                switch ($key) {
                    case 0:
                        $keyword = trim(str_replace(['[', ']'], '', $keyword));
                        [$ip, $user, $time, $timeZone] = explode(' ', $keyword);
                        $array['ip']   = $ip;
                        $array['user'] = $user;
                        $array['time'] = Carbon::create($time . ' ' . $timeZone)->format('Y-m-d H:i:s');
                        break;
                    case 1:
                        try {
                            [$method, $uri, $http] = explode(' ', trim($keyword));
                            $array['method'] = $method;
                            $array['uri']    = $uri;
                            $array['http']   = $http;
                        } catch (\ErrorException $errorException) {
                            $array['method'] = $keyword;
                            $array['uri']    = $keyword;
                            $array['http']   = $keyword;
                        }
                        break;
                    case 2:
                        try {
                            [$httpCode, $size] = explode(' ', trim($keyword));
                            $array['http_code'] = $httpCode;
                            $array['size']      = $size;
                        } catch (\ErrorException $errorException) {
                            $array['http_code'] = 'UnKnow';
                            $array['size']      = 'UnKnow';
                        }
                        break;
                    case 3:
                        $array['return'] = $keyword;
                        break;
                    case 5:
                        $array['user_agent'] = $keyword;
                        break;
                    default:
                        $array[] = '';

                }
            }

            $array['string'] = $log;
            $array           = array_filter($array);

            //
            $ua                                   = new UserAgent($array['user_agent'] ?? '');
            $array['user_agent_info']['platform'] = $ua->platform();
            $array['user_agent_info']['browser']  = $ua->browser();
            $array['user_agent_info']['version']  = $ua->version();
            $array['is_robot']                    = $ua->isRobot();
            $array['is_mobile']                   = $ua->isMobile();

            //
            if (isset($array['uri'])) {
                $array['is_warning'] = !(Str::startsWith($array['uri'], ['/']) || $array['uri'] === '/');
            } else {
                $array['is_warning'] = true;
            }

            //
            $array['is_error'] = !HttpCodes::isSuccessful($array['http_code']);

            $logs_data[] = $array;
        }

        return collect(array_reverse($logs_data));
    }

    public function getByWhere($logs, $params)
    {

        if (!empty($params['ip'])) {
            $logs = $logs->where('ip', $params['ip']);
        }

        if (!empty($params['method'])) {
            $logs = $logs->where('method', $params['method']);
        }

        if (!empty($params['http_code'])) {
            $logs = $logs->where('http_code', $params['http_code']);
        }

        if (!empty($params['uri'])) {
            $logs = $logs->where('uri', $params['uri']);
        }

        $warningValue = !empty($params['is_warning']) && $params['is_warning'] != null;
        ($warningValue);
        if ($warningValue) {
            $logs = $logs->where('is_warning', $params['is_warning'] ? true : false);
        }

        $isErrorValue = !empty($params['is_error']) && $params['is_error'] != null;
        if ($isErrorValue) {
            $logs = $logs->where('is_error', $params['is_error'] ? true : false);
        }

        $isRobotValue = !empty($params['is_robot']) && $params['is_robot'] != null;
        if ($isRobotValue) {
            $logs = $logs->where('is_robot', $params['is_robot'] ? true : false);
        }

        $isMobileValue = !empty($params['is_mobile']) && $params['is_mobile'] != null;
        if ($isMobileValue) {
            $logs = $logs->where('is_mobile', $params['is_mobile'] ? true : false);
        }

        $timeValue = !empty($params['start_at']) && $params['start_at'] != null && isset($params['end_at']) && $params['end_at'] != null;
        if ($timeValue) {
            $logs = $logs->whereBetween('time', [$params['start_at'], $params['end_at']]);
        }

        return $logs;

    }

}
